package com.yike.product.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yike.common.exception.BusinessException;
import com.yike.common.tool.LoginUtil;
import com.yike.product.entity.GoodsCategory;
import com.yike.product.mapper.GoodsCategoryMapper;
import com.yike.product.param.GoodsCategoryParam;
import com.yike.product.service.GoodsCategoryService;
import com.yike.product.param.GoodsCategoryPageParam;
import com.yike.common.base.BaseServiceImpl;
import com.yike.common.pagination.Paging;
import com.yike.common.pagination.PageInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yike.product.vo.GoodsCategoryTreeVo;
import com.yike.product.vo.GoodsCategoryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * 商品分类 服务实现类
 *
 * @author Sakura
 * @since 2024-10-18
 */
@Slf4j
@Service
public class GoodsCategoryServiceImpl extends BaseServiceImpl<GoodsCategoryMapper, GoodsCategory> implements GoodsCategoryService {

    @Autowired
    private GoodsCategoryMapper goodsCategoryMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveGoodsCategory(GoodsCategoryParam goodsCategoryParam) throws Exception {
        // 先判断名称是否有重复
        GoodsCategory goodsCategory = goodsCategoryMapper.selectOne(Wrappers.lambdaQuery(GoodsCategory.class)
                .eq(GoodsCategory::getName, goodsCategoryParam.getName()));
        if (goodsCategory != null) {
            throw new BusinessException("当前分类已存在，请勿重复添加");
        }
        // 保存分类信息
        goodsCategory = new GoodsCategory();
        BeanUtils.copyProperties(goodsCategoryParam, goodsCategory);
        goodsCategory.setCreateBy(LoginUtil.getUserId());
        return super.save(goodsCategory);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateGoodsCategory(GoodsCategoryParam goodsCategoryParam) throws Exception {
        // 先获取当前分类信息
        GoodsCategory goodsCategory = goodsCategoryMapper.selectById(goodsCategoryParam.getId());
        if (goodsCategory == null) {
            throw new BusinessException("分类信息异常");
        }
        // 校验修改的时候是否和其它分类名称重复
        Integer checkNum = goodsCategoryMapper.selectCount(Wrappers.lambdaQuery(GoodsCategory.class)
                .eq(GoodsCategory::getName, goodsCategoryParam.getName())
                .ne(GoodsCategory::getId, goodsCategoryParam.getId()));
        if (checkNum > 0) {
            throw new BusinessException("当前分类已存在，请勿重复添加");
        }

        // 修改分类信息
        BeanUtils.copyProperties(goodsCategoryParam, goodsCategory);
        goodsCategory.setUpdateBy(LoginUtil.getUserId());
        return super.updateById(goodsCategory);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteGoodsCategory(Long id) throws Exception {
        return super.removeById(id);
    }

    @Override
    public GoodsCategoryVo getGoodsCategory(Long id) throws Exception {
        return goodsCategoryMapper.getGoodsCategory(id);
    }

    @Override
    public Paging<GoodsCategoryVo> getGoodsCategoryPageList(GoodsCategoryPageParam goodsCategoryPageParam) throws Exception {
        Page<GoodsCategory> page = new PageInfo<>(goodsCategoryPageParam);
        IPage<GoodsCategoryVo> iPage = goodsCategoryMapper.getGoodsCategoryList(page, goodsCategoryPageParam);
        return new Paging<GoodsCategoryVo>(iPage);
    }

    @Override
    public List<GoodsCategoryTreeVo> tree() throws Exception {
        List<GoodsCategoryVo> goodsCategoryVos = goodsCategoryMapper.getAllGoodsCategory();
        int num = 0; // 添加一个遍历层数，防止数据异常导致递归死循环
        return getChildCategory(0L, goodsCategoryVos, num);
    }

    private List<GoodsCategoryTreeVo> getChildCategory(Long parentId, List<GoodsCategoryVo> categoryVos, int num) throws Exception {
        num++;// 控制遍历次数，防止因数据问题导致无限循环内存溢出，目前最大支持10层
        if (num > 10) {
            log.error("分类数据异常 parentId：" + parentId);
            throw new BusinessException(500, "部门数据异常，请联系管理人员");
        }

        List<GoodsCategoryTreeVo> resultList = new ArrayList<>();

        for (GoodsCategoryVo categoryVo : categoryVos) {
            if (parentId.equals(categoryVo.getParentId())) {
                GoodsCategoryTreeVo categoryTreeVo = new GoodsCategoryTreeVo();
                BeanUtils.copyProperties(categoryVo, categoryTreeVo);
                // 通过当前ID获取子分类
                List<GoodsCategoryTreeVo> childCategoryTreeVos = getChildCategory(categoryVo.getId(), categoryVos, num);
                categoryTreeVo.setChildren(childCategoryTreeVos);

                resultList.add(categoryTreeVo);
            }
        }

        return resultList;
    }

}
